//---------------------------------------------------------------------
// This file is part of the Microsoft BizTalk Server 2006 SDK
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// This source code is intended only as a supplement to Microsoft BizTalk
// Server 2006 release and/or on-line documentation. See these other
// materials for detailed information regarding Microsoft code samples.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//---------------------------------------------------------------------
using System;
using System.IO;


namespace MsPartners.Unisys.BizTalkAdapters.AdapterWizard
{
	/// <summary>
	/// This class generates a registry file for the adapter based
	/// on the values chosen in the wizard.
	/// </summary>
	internal class AdapterRegistry
	{
		private const int eProtocolSupportsReceive = 1;	//Adapter supports receive operations. 
		private const int eProtocolSupportsTransmit = 2;	//Adapter supports send operations. 
		private const int eProtocolRequireSingleInstancePerServer = 4;	//Adapter requires a single instance per server. 
		private const int eProtocolReceiveIsCreatable = 8;	//Receive handler of adapter is hosted in-process. 
		private const int eProtocolIsApplicationProtocol = 16;	//Adapter is application protocol. 
		private const int eProtocolDeleteProtected = 32;	//Adapter is delete protected. 
		private const int eProtocolStaticHandlers = 64;	//Adapter supports static handlers. 
		private const int eProtocolSupportsRequestResponse = 128;	//Adapter supports request-response operations. 
		private const int eProtocolSupportsSolicitResponse = 256;	//Adapter supports solicit-response operations. 
		private const int eProtocolSupportsSOAP = 512;	//Adapter supports the SOAP protocol. 
		private const int eOutboundProtocolRequiresContextInitialization = 1024;	//Adapter uses adapter framework user interface for send handler configuration. 
		private const int eInboundProtocolRequiresContextInitialization = 2048;	//Adapter uses adapter framework user interface for receive handler configuration 
		private const int eReceiveLocationRequiresContextInitialization = 4096;
		private const int eTransmitLocationRequiresContextInitialization = 8192;	//Adapter uses adapter framework user interface for send location configuration. 
		private const int eSupportsOrderedDelivery = 16384; //Adapter supports ordered delivery.
		private const int eInitTransmitterOnServiceStart = 32768; //Send adapter starts when the service starts instead of when it sends the first message.

		private string transportCLSID = Guid.NewGuid().ToString();
		private string inboundCLSID = Guid.NewGuid().ToString();
		private string outboundCLSID = Guid.NewGuid().ToString();
		private string transportType = null;
		private string appID = Guid.NewGuid().ToString();
		private string constraints = null;
		private string codeNamespace = null;
		private string projectDirectory = null;
		private string propertyNamespace = null;
		private string aliases = null;
		private bool adapterSupportsReceive = false;
		private bool adapterSupportsTransmit = false;
		private bool receiveAdapterSupportsReqRsp = false;
		private bool transmitAdapterSupportsSolRsp = false;
		private bool receiveAdapterIsIsolated = false;
		private bool transmitAdapterHasHandler = false;
		private bool receiveAdapterHasHandler = false;
		private SupportedLanguages requestedLanguage = SupportedLanguages.CSharp;

		public AdapterRegistry()
		{
		}

		/// <summary>
		/// Creates the registry file needed to register the adapter
		/// with BizTalk
		/// </summary>
		/// <param name="strFilename"></param>
		public void CreateRegFile(string strFilename)
		{
			int NumConstraints = 0;

			if (adapterSupportsReceive)
			{
				NumConstraints |= eProtocolSupportsReceive;
				NumConstraints |= (receiveAdapterSupportsReqRsp ? eProtocolSupportsRequestResponse : 0);
				NumConstraints |= (!receiveAdapterIsIsolated ? eProtocolReceiveIsCreatable : 0);
				NumConstraints |= eInboundProtocolRequiresContextInitialization;
				NumConstraints |= eReceiveLocationRequiresContextInitialization;
			}
			if (adapterSupportsTransmit)
			{
				NumConstraints |= eProtocolSupportsTransmit;
				NumConstraints |= (transmitAdapterSupportsSolRsp ? eProtocolSupportsSolicitResponse : 0);
				NumConstraints |= eOutboundProtocolRequiresContextInitialization;
				NumConstraints |= eTransmitLocationRequiresContextInitialization;
			}
			constraints = NumConstraints.ToString("x8");

			using (TextWriter regFile = new StreamWriter(strFilename, false))
			{
				regFile.WriteLine("Windows Registry Editor Version 5.00");
				regFile.WriteLine("[HKEY_CLASSES_ROOT\\CLSID\\{" + transportCLSID + "}]");
				regFile.WriteLine("@=\"" + transportType + " Adapter\"");
				regFile.WriteLine("\"AppID\"=\"{" + appID + "}\"");
				regFile.WriteLine();
				regFile.WriteLine("[HKEY_CLASSES_ROOT\\CLSID\\{" + transportCLSID + "}\\BizTalk]");
				regFile.WriteLine("@=\"BizTalk\"");
				regFile.WriteLine("\"TransPortType\"=\"" + transportType + "\"");
				regFile.WriteLine("\"Constraints\"=dword:" + constraints);
				regFile.WriteLine();
				if (adapterSupportsTransmit)
				{
					if (transmitAdapterHasHandler)
					{
						regFile.WriteLine("\"OutboundProtocol_PageProv\"=\"{2DE93EE6-CB01-4007-93E9-C3D71689A283}\"");
					}
					regFile.WriteLine("\"TransmitLocation_PageProv\"=\"{2DE93EE6-CB01-4007-93E9-C3D71689A282}\"");
				}
				if (adapterSupportsReceive)
				{
					if (receiveAdapterHasHandler)
					{
						regFile.WriteLine("\"InboundProtocol_PageProv\"=\"{2DE93EE6-CB01-4007-93E9-C3D71689A281}\"");
					}
					regFile.WriteLine("\"ReceiveLocation_PageProv\"=\"{2DE93EE6-CB01-4007-93E9-C3D71689A280}\"");
				}
				regFile.WriteLine();
				if (adapterSupportsTransmit)
				{
					regFile.WriteLine("\"OutboundEngineCLSID\"=\"{" + outboundCLSID + "}\"");
					regFile.WriteLine("\"OutboundTypeName\"=\"" + codeNamespace + ".Runtime." + transportType + "Transmitter." + transportType + "TransmitAdapter\"");
					regFile.WriteLine("\"OutboundAssemblyPath\"=\"" + (projectDirectory + @"\Run-Time\" + transportType + @"Transmit\bin\" + (requestedLanguage == SupportedLanguages.CSharp ? @"Debug\" : "") + transportType + "TransmitAdapter.dll\"").Replace(@"\", @"\\"));
					regFile.WriteLine();
				}
				if (adapterSupportsReceive)
				{
					regFile.WriteLine("\"InboundEngineCLSID\"=\"{" + inboundCLSID + "}\"");
					regFile.WriteLine("\"InboundTypeName\"=\"" + codeNamespace + ".Runtime." + transportType + "Receiver." + transportType + "ReceiveAdapter\"");
					regFile.WriteLine("\"InboundAssemblyPath\"=\"" + (projectDirectory + @"\Run-Time\" + transportType + @"Receive\bin\" + (requestedLanguage == SupportedLanguages.CSharp ? @"Debug\" : "") + transportType + "ReceiveAdapter.dll\"").Replace(@"\", @"\\"));
					regFile.WriteLine();
				}
				regFile.WriteLine("\"AdapterMgmtTypeName\"=\"" + codeNamespace + "." + transportType + "DesignTime.AdapterManagement\"");
				regFile.WriteLine("\"AdapterMgmtAssemblyPath\"=\"" + (projectDirectory + @"\Design-Time\bin\" + (requestedLanguage == SupportedLanguages.CSharp ? @"Debug\" : "") + transportType + "AdapterManagement.dll\"").Replace(@"\", @"\\"));
				regFile.WriteLine();
				if (adapterSupportsTransmit)
				{
					regFile.WriteLine("\"AliasesXML\"=\"" + GetAdapterAliasList(aliases) + "\"");
				}
				regFile.WriteLine("\"PropertyNameSpace\"=\"" + propertyNamespace + "\"");
				regFile.WriteLine();
				if (adapterSupportsReceive)
				{
					if (receiveAdapterHasHandler)
					{
						regFile.WriteLine("\"ReceiveHandlerPropertiesXML\"=\"<CustomProps><AdapterConfig vt=\\\"8\\\"/></CustomProps>\"");
					}
					regFile.WriteLine("\"ReceiveLocationPropertiesXML\"=\"<CustomProps><AdapterConfig vt=\\\"8\\\"/></CustomProps>\"");
				}
				if (adapterSupportsTransmit)
				{
					if (transmitAdapterHasHandler)
					{
						regFile.WriteLine("\"SendHandlerPropertiesXML\"=\"<CustomProps><AdapterConfig vt=\\\"8\\\"/></CustomProps>\"");
					}
					regFile.WriteLine("\"SendLocationPropertiesXML\"=\"<CustomProps><AdapterConfig vt=\\\"8\\\"/></CustomProps>\"");
				}
				regFile.WriteLine();
				regFile.WriteLine("[HKEY_CLASSES_ROOT\\CLSID\\{" + transportCLSID + "}\\Implemented Categories]");
				regFile.WriteLine();
				regFile.WriteLine("[HKEY_CLASSES_ROOT\\CLSID\\{" + transportCLSID + "}\\Implemented Categories\\{7F46FC3E-3C2C-405B-A47F-8D17942BA8F9}]");
				regFile.Close();
			}
		}

		private string GetAdapterAliasList(string aliases)
		{
			string aliasList = "<AdapterAliasList>";
			
			foreach(string str in aliases.Split(",".ToCharArray()))
			{
				aliasList += "<AdapterAlias>" + str + "</AdapterAlias>";
			}
			return aliasList + "</AdapterAliasList>";
		}

		public string InboundCLSID
		{
			get	{ return inboundCLSID; }
		}

		public string OutboundCLSID
		{
			get	{ return outboundCLSID; }
		}

		public string Aliases
		{
			get { return aliases; }
			set { aliases = value; }
		}

		public string PropertyNamespace
		{
			get { return propertyNamespace; }
			set { propertyNamespace = value; }
		}

		public string ProjectDirectory
		{
			get { return projectDirectory; }
			set { projectDirectory = value; }
		}

		public string TransportType
		{
			get { return transportType; }
			set { transportType = value; }
		}

		public string CodeNamespace
		{
			get { return codeNamespace; }
			set { codeNamespace = value; }
		}

		public bool AdapterSupportsReceive
		{
			get { return adapterSupportsReceive; }
			set { adapterSupportsReceive = value; }
		}

		public bool AdapterSupportsTransmit
		{
			get { return adapterSupportsTransmit; }
			set { adapterSupportsTransmit = value; }
		}

		public bool ReceiveAdapterIsIsolated
		{
			get { return receiveAdapterIsIsolated; }
			set { receiveAdapterIsIsolated = value; }
		}

		public bool ReceiveAdapterSupportsReqRsp
		{
			get { return receiveAdapterSupportsReqRsp; }
			set { receiveAdapterSupportsReqRsp = value; }
		}

		public bool TransmitAdapterSupportsSolRsp
		{
			get { return transmitAdapterSupportsSolRsp; }
			set { transmitAdapterSupportsSolRsp = value; }
		}

		public bool TransmitAdapterHasHandler
		{
			get { return transmitAdapterHasHandler; }
			set { transmitAdapterHasHandler = value; }
		}

		public bool ReceiveAdapterHasHandler
		{
			get { return receiveAdapterHasHandler; }
			set { receiveAdapterHasHandler = value; }
		}

		public SupportedLanguages RequestedLanguage
		{
			get { return requestedLanguage; }
			set { requestedLanguage = value; }
		}
	}
}
